<template>
    <div class="table">
        <!--table头：搜索|搜索相关按钮-->
        <div class="tableHeader">
            <!--搜索-->
            <div class="search">
                <el-input placeholder="搜索包含:员工号||姓名||部门||中心||班组" v-model="search"></el-input>
            </div>
            <!--搜索相关的button-->
            <div class="headerButton">
                <el-button @click="allreset">恢复所有过滤条件</el-button>
                <el-button @click="checkOverTime">检测过期</el-button>
                <el-button @click="exportExcel">导出为excel</el-button>
            </div>
        </div>
        <!--搜索小方块-->
        <div class="tableremark">
            <span v-for="(i,index) in header" :key="index" class="tableremarkitem">
                <span class="react" :style="{background:i.color}"></span>
                {{i.value}}
            </span>
        </div>
        <!--表格(相关提示)
        id:(代码中)用于获取DOM
        border:是否加上边框
        ref:(代码中)清除过滤条件
        data->filterTableData
        @cell-click:(代码中)点击单元格触发的事件
        -->
        <el-table
            id = "specialcarddytableDom"
            border
            ref="tableRef"
            :data="filterTableData"
            :scrollbar-always-on="true"
            style="width: 100%"
            @cell-click="cellclick"
            :cell-style="cellStyle"
            :max-height="screenhight"
            v-loading="loading"
            @filter-change="filterChange"
            @sort-change="slotChange"
        >
            <el-table-column prop="peopleNum" sortable label="员工号" width="130"/>
            <el-table-column prop="peopleName" label="姓名" width="100"/>
            <el-table-column prop="department" sortable label="部门" width="100"/>
            <el-table-column prop="center" sortable label="中心" width="100"/>
            <el-table-column prop="className" sortable label="班组" width="150"/>
            <!--关于低压一般为领用日期-->
            <el-table-column prop="cardId"
                             label="证书id"
                             :sortable="true"
                             :sort-method="(a,b) => sortMethod(a,b,'cardId')">
            </el-table-column>
            <el-table-column prop="firstExamTime"
                             label="初发证日期"
                             :sortable="true"
                             :sort-method="(a,b) => sortMethod(a,b,'firstExamTime')"
                             :formatter="dateFormat"
                             width="150"
                             :filters='month'
                             :filter-method="filterHandler"
                             :filter-multiple="false">
            </el-table-column>
            <el-table-column prop="validityDate"
                             label="应复审日期"
                             :formatter="dateFormat"
                             :sortable="true"
                             :sort-method="(a,b) => sortMethod(a,b,'validityDate')"
                             width="150"
                             :filters='month'
                             :filter-method="filterHandler"
                             :filter-multiple="false">
            </el-table-column>
            <el-table-column prop="nextExamTime"
                             label="有效期结束日期"
                             :sortable="true"
                             :sort-method="(a,b) => sortMethod(a,b,'nextExamTime')"
                             :formatter="dateFormat"
                             width="180"
                             :filters='month'
                             :filter-method="filterHandler"
                             :filter-multiple="false">
            </el-table-column>
        </el-table>
        <!--弹出框-->
        <el-dialog
            v-model="dialogVisible"
            title="详情"
            width="30%"
            :before-close="handleClose"
        >
            <div v-if="loadData.listLableName!=='证书id'">
                <div>当前需要修改的类目：{{loadData.listLableName}}</div>
                <div>上一次{{loadData.listLableName}}：{{loadData.lastTime}}</div>
                <div>到期日期:{{loadData.expirationTime}}</div>
                <div>到期月数:{{ loadData.expirationMonth }}</div>
                <div>
                    <span class="demonstration">选择{{loadData.listLableName}}:</span>
                    <el-date-picker
                        v-model="datavalue"
                        type="date"
                        placeholder="选择日期"
                        :shortcuts="shortcuts"
                    />
                </div>
            </div>
            <div v-else>
                <div>当前需要修改的类目：{{loadData.listLableName}}</div>
                <div>请输入证书id：<el-input placeholder="请输入证书id" v-model="datastring"></el-input></div>
            </div>
            <template #footer="scope">
                <span class="dialog-footer">
                    <el-button @click="cancel">取消</el-button>
                    <el-button type="primary" @click="submit(scope.$index, scope.row)">提交</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>

<script setup>
import {onBeforeUnmount, onMounted, ref, computed, nextTick} from "vue";
import {selectLabor, changeLaborinsDay, selectSpecialDY, selectSpecialDG} from "../../api";    //接口
import {throttle} from "lodash";    //节流防抖
import {tableHooks} from "../../api/tableHooks.js";    //表格的hooks
import {useStore} from "vuex";    //状态管理
import {bus} from "../../api/eventBus";
import dayjs from "dayjs";
let store = useStore()



/*初始化配置以及hooks导入*/
//配置时效
let config = computed(()=>{return store.state.config.configObj;});
//过期配置
let timeoutList = {
    validityDate:config.value.certificate.dyfs.indate,    //低压
    nextExamTime:config.value.certificate.dy.indate,    //低压复审
}


/* hooks-导出参数
exportExcelFromTableDom 导出表格 在导出表格时候用
showColor 是否显示颜色 //在是否检测过期的函数里取反function checkOverTime(){
colorList 颜色列表,在header里用
initTableHookProperty 初始化必须调用该函数
cellStyle 在el-table里用 设置:cell-style="cellStyle"
*/

let {exportExcelFromTableDom,showColor,colorList,initTableHookProperty,cellStyle} = tableHooks();
//初始化表的属性
initTableHookProperty(['peopleNum','peopleName','department','center','className','cardId','firstExamTime','validityDate','nextExamTime'], timeoutList, "#specialcarddytableDom > div.el-table__inner-wrapper > div.el-table__body-wrapper > div > div.el-scrollbar__wrap.el-scrollbar__wrap--hidden-default > div > table", 'specialcarddytableDom')


//加载动画
let loading = computed(()=>{return store.state.loading;});
//初始化头部的小方块颜色和描述。
const header = ref([
    {color:colorList[0],value:'已过期~本月过期'},
    {color:colorList[1],value:'0~1月'},
    {color:colorList[2],value:'0~2月'},
    {color:colorList[3],value: '0~3月'},
    {color:colorList[4],value: '0~4月'}
])
// 时间选择器的格式化
const shortcuts = [{text: '今日', value: new Date()}]


//视口的高度
let screenhight = ref( window.innerHeight-143)
//监听高度
let throll= throttle(()=>{
    console.log("窗口变化了");
    screenhight.value = window.innerHeight-143;//菜单栏53;pading:10;按钮:42
},10)
// TODO (未使用)账号的基本信息
let staffInfo = computed(()=>{return store.state.staffInfo;})


/*初始化数据处理*/
//后端：一定有的数据  {center: "通号一中心",className: "2号线轨旁1工班",department: "通号部",id: 45,peopleName: "俞杰",peopleNum: "C0007500"}
//后端：传过来可能没有的数据{fingerShoes?: initdate,fingerShoesSize?: number,fluorescentClothes?:initdate,helmet?:initdate,safetyShoes?:initdate,safetyShoesSize?:number}
//后端请求回来的数据
let TableContentData = ref([])
//需要补全的属性数据
let maybeThereIsAProperty = ['cardId','firstExamTime','validityDate','nextExamTime']
/**
 * 补全缺失数据函数
 * @param item    传入的数组的单个item值
 */
function init(item){
    for(let i = 0;i<maybeThereIsAProperty.length;i++){
        let initdate = {date: undefined,day: undefined,hours: undefined,minutes: undefined,month: undefined,nanos: undefined,seconds: undefined,time: undefined,timezoneOffset: -480,year: undefined}
        if (!item.hasOwnProperty(maybeThereIsAProperty[i])){
            if(maybeThereIsAProperty[i]!=='cardId'){
                item[maybeThereIsAProperty[i]] = initdate
            }else{
                item[maybeThereIsAProperty[i]] = ''
            }
        }
    }
    item.firstExamTimeOverMonth = calcMonth(item.firstExamTime.time,'firstExamTime');
    item.validityDateOverMonth = calcMonth(item.validityDate.time,'validityDate');
    item.nextExamTimeOverMonth = calcMonth(item.nextExamTime.time,'nextExamTime');
}


/**
 * 格式化数据
 * @param row    元组
 * @param column    属性
 * @return {string}    返回一个字符串
 */
function dateFormat(row, column) {
    let date = row[column.property];
    if (date !== undefined){
        if(date.time !== undefined){
            return dayjs(date.time).format("YYYY-MM-DD");
        }else {
            return '请填写数据！'
        }
    }else{
        console.log('date2',date,'row2',row,'column2',column.property)
    }
}


/**
 * 计算月份
 * @param thisGoodsTime    物品的时间
 * @param property    属性名
 * @return {number}    返回过期月份数
 * @remarks standardMonth 为一个月所对应的毫秒数
 */
function calcMonth(thisGoodsTime,property) {
    let standardMonth = 2592000000
    //要过期的毫秒数
    let expirationTime = thisGoodsTime + timeoutList[property];
    //今天的毫秒数
    let nowTime = new Date().getTime();
    let month = Math.floor((expirationTime-nowTime)/ standardMonth);
    return month;
}


/*生命周期*/
//挂载：1.请求数据 2.初始化数据 3.计算过期时间并且刷新数据
onMounted(async () => {
    window.addEventListener('resize',throll);
    try {
        let block = {
            classNum:staffInfo.value.userNum,
            centerId:staffInfo.value.centerId,
            jurisdiction:staffInfo.value.jurisdiction
        }
        let res = await selectSpecialDG(block)
        TableContentData.value = [...res.specialList]
        TableContentData.value.forEach((item)=>{init(item);})
    } catch (err) {
        console.log('err', err)
    }
    checkOverTime()    //查看过期的时间
})
//离开页面之后 1.解除对窗口的监听
onBeforeUnmount(()=>{
    bus.off('table-data-change')
    window.removeEventListener('resize',throll);
})



/*操作表格*/
/**
 * 排序规则
 * @param before    表格中前一条数据
 * @param after    表格中后一条数据
 * @param key    属性名
 * @return {number}    排好序的数组
 */
function sortMethod(before,after,key){
    try {
        return (before[key]!== '' && before[key]!= null) - (after[key]!== '' && after[key]!= null) || before[key].time - after[key].time;
    }catch (err){
        console.log(err)
    }
}
/**
 * 排序之后
 */
function slotChange(){
    nextTick(() => {bus.emit('table-data-change');});
}
/**
 * 检测过期
 */
function checkOverTime(){
    showColor.value=!showColor.value
}

/*筛选*/
//筛选参数:月份
let month = ref([
    { text: '距离过期还有1月', value: 1 },
    { text: '距离过期还有2月', value: 2 },
    { text: '距离过期还有3月', value: 3 },
    { text: '距离过期还有4月', value: 4 },
    { text: '距离过期还有5月', value: 5 },
    { text: '距离过期还有6月', value: 6 },
    { text: '距离过期还有7月', value: 7 },
    { text: '距离过期还有8月', value: 8 },
    { text: '距离过期还有9月', value: 9 },
    { text: '距离过期还有10月', value: 10 },
    { text: '距离过期还有11月', value: 11 },
    { text: '距离过期还有12月', value: 12 },
])
/**
 * 根据月份过滤
 * @param value    月份所对应的值
 * @param row    元组
 * @param column    关键字
 * @return {boolean}    返回的布尔值
 */
function filterHandler(value,row,column){
    const property = column['property']
    return row[property+'OverMonth'] <= value
}
/**
 * 过滤改变之后
 */
function filterChange(){
    console.log('1')
    nextTick(() => {bus.emit('table-data-change');})
}

//绑定table上的节点
const tableRef = ref(null)
/**
 * 恢复所有筛选条件
 */
const allreset = () => {
    tableRef.value.clearFilter()
    nextTick(() => {bus.emit('table-data-change');})
}



/*弹出框*/
//生产日期
let datavalue = ref('')
//初始鞋码
let datastring = ref('')
//是否显示弹出框
let dialogVisible = ref(false)
/**
 * 关闭弹出框
 */
function handleClose() {
    dialogVisible.value = false;
    reset()
}
/**
 * 取消弹出款
 */
function cancel(){
    dialogVisible.value = false;
    reset()
}



/*搜索功能*/
//注释：table的数据帮在filterTableData上
//1.toLowerCase()转为小写
//2.includes()方法用于判断字符串是否包含指定的子字符串
const search = ref('')
const filterTableData = computed(() =>{
    let res = TableContentData.value.filter(
        (data) =>
            !search.value || data.peopleName.includes(search.value) //员工的姓名
            || data.peopleNum.includes(search.value) //员工号
            || data.department.includes(search.value) //部门
            || data.center.includes(search.value) //中心
            || data.className.includes(search.value) //班组名称
    )
    /*必须在下一次渲染结束触发该事件,因为table是获取dom数据,直接在该计算属性中触发dom还没来得及更新,故需要在下次渲染dom结束后触发该事件*/
    nextTick(() => {bus.emit('table-data-change');});
    return res;
});



//把ID和属性记录下来
let loadData = ref({
    listId:"",    //元组所对应的id
    listLableName: "",    //关键字(中文->根据table上拉下来的)
    listName:'',    //关键字(英文->后端传过来的)
    lastTime:"",    //最近时间
    expirationTime:"",    //过期时间
    expirationMonth:"",    //过期天数
    string:"", //鞋码之类字符类型
    changedData: "",    //修改日期
})
let changeRow = null;
//点击单元格
function cellclick (row, column) {
    let content = ['cardId','firstExamTime','validityDate','nextExamTime']
    if(content.indexOf(column.property) !== -1){
        dialogVisible.value = true;
        changeRow = row;
        loadData.value.listId = row.id;
        loadData.value.listLableName = column.label;
        loadData.value.listName = column.property;
        loadData.value.string = row[column.property];
        loadData.value.expirationTime = dayjs(row[column.property].time).format("YYYY-MM-DD");
        loadData.value.expirationMonth = Math.floor((row[column.property].time - new Date().getTime())/ 2592000000);
        //如果有时间就显示时间，如果不是时间就显示数值！
        if(row[column.property].time){
            loadData.value.lastTime = dayjs(row[column.property].time).format("YYYY-MM-DD");
        }else{
            loadData.value.string = row[column.property]
        }
    }
}


/*提交数据*/
/*判断打开的弹窗是修改劳保用品日期，还是修改劳保用品数值*/
/**
 * 为日期(修改过期时间)
 */
async function judgeDate() {
    loadData.value.changedData = dayjs(datavalue.value).format("YYYY-MM-DD 00:00:00")
    let block = {
        listId: loadData.value.listId,
        listName: loadData.value.listName,
        changedData: loadData.value.changedData,
        tableName: "specialcarddg"
    }
    let res = await changeLaborinsDay(block)
    if (res.code === 200) {
        changeRow[loadData.value.listName] = datavalue.value;
        changeRow[loadData.value.listName].time = datavalue.value.getTime();
        dialogVisible.value = false;
        await nextTick(() => {bus.emit('table-data-change');}); //刷新颜色
    }
}

/**
 * 为数值(修改物品属性)
 */
async function judgeData() {
    loadData.value.changedData = datastring.value
    let block = {
        listId: loadData.value.listId,
        listName:loadData.value.listName,
        changedData:loadData.value.changedData,
        tableName: "specialcarddg"
    }
    let res = await changeLaborinsDay(block)
    if(res.code === 200 ){
        changeRow[loadData.value.listName] = datastring.value;
        dialogVisible.value = false;
        await nextTick(() => {bus.emit('table-data-change');}); //刷新颜色
    }
}

/**
 * 提交数据
 * @return {Promise<void>}
 */
async function submit() {
    try {
        ElMessageBox.confirm('注意，其他为领用日期哦！')
            .then(async () => {
                //如果初始日期为空字符
                if(datavalue.value !== ''){
                    await judgeDate()
                }else if(datastring.value !== ''){
                    await judgeData()
                }
                reset()
                dialogVisible.value = false
            }).catch((err) => {
            console.log(err)
        })
    } catch (err) {
        console.log(err)
    }
}



//导出表格
function exportExcel(){
    if(TableContentData.value.length <=0){
        return;
    }
    exportExcelFromTableDom();
}


//初视化数据
function reset(){
    //弹窗的数据
    loadData.value = {listId:"", listLableName: "", listName:'', lastTime:"", expirationTime:"", expirationMonth:"", string:"", changedData: "",}
    //弹窗时间
    datavalue.value = ''
    //弹窗数值
    datastring.value = ''
}

</script>

<style scoped lang="scss">
.table {
    padding: 10px;
    position: relative;
    .tableHeader{
        display: flex;
        flex-direction: row;
        .search{
            display: flex;
            flex-direction: row;
            width: 400px;
        }
        & > *{
            margin-right: 10px;
            margin-bottom: 10px;
        }
    }
    .tableremark{
        margin-bottom: 5px;
        .tableremarkitem{
            display:inline-flex;
            align-items: center;
            height: 20px;
            margin-right: 10px;
            .react{
                display: inline-block;
                width: 16px;
                height: 16px;
                border: 2px solid #000000;
                border-radius: 5px;
            }
        }
    }
    .headerButton{
        position: absolute;
        right:10px;
    }
}
.black{
    background: #000;
}
.m-2{
    margin-right: 10px;
}
footer{
    color: #5e6063;
}
</style>

